package com.apes.fn.scm.insuranceRules;

import com.alibaba.fastjson.JSONObject;
import com.apes.crm.business.model.InsuranceCompany;
import com.apes.crm.business.repository.InsuranceCompanyRepository;
import com.apes.framework.api.DomainService;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.logger.ApesLoggerService;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.area.model.Area;
import com.apes.scm.masterdata.area.repository.AreaRepository;
import com.apes.scm.masterdata.frame.model.Dept;
import com.apes.scm.masterdata.frame.model.Store;
import com.apes.scm.masterdata.frame.repository.DeptRepository;
import com.apes.scm.masterdata.frame.repository.StoreRepository;
import com.apes.scm.rbac.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import javax.swing.*;
import java.util.*;

/**
 * @ClassName : InsuranceRuleService
 * @Description : 保险规则业务层
 * @Author : WSJ
 * @Date: 2020-04-07 11:18
 */
@Service("insuranceRuleService")
public class InsuranceRuleService extends DomainService {
    @Autowired
    private InsuranceRuleRepository insuranceRuleRepository;
    @Autowired
    private AreaRepository areaRepository;


    public InsuranceRule save(SimpleRequest request) {
        InsuranceRule insuranceRule = request.getO(InsuranceRule.class);
        //getCityAndProvince(insuranceRule);
        setDamagePoint(insuranceRule);
        insuranceRule = insuranceRuleRepository.saveAndFlush(insuranceRule);
        dealWithDeptList(insuranceRule);
        return insuranceRule;
    }

    /**
     * 获取省市区
     * @param insuranceRule
     */
    private void getCityAndProvince(InsuranceRule insuranceRule) {
        //获取城市
        Area city = insuranceRule.getCity();
        //获取省份
        String provinceId = city.getParent();
        Area province = areaRepository.findOne(provinceId);
        insuranceRule.setProvince(province);
    }

    public InsuranceRule update(SimpleRequest request) {
        InsuranceRule insuranceRule = request.getO(InsuranceRule.class);
        //获取城市
        //getCityAndProvince(insuranceRule);
        setDamagePoint(insuranceRule);
        insuranceRule = insuranceRuleRepository.saveAndFlush(insuranceRule);
        dealWithDeptList(insuranceRule);
        return insuranceRule;
    }


    public InsuranceRule delete(SimpleRequest request) throws Exception  {
        checkData(request);
        InsuranceRule insuranceRule = request.getO(InsuranceRule.class);
        insuranceRule.setDeleteDate(new Date());
        insuranceRule.setDeleteUid(this.getPerson(request));
        insuranceRule.setValid(false);
        return  insuranceRuleRepository.saveAndFlush(insuranceRule);
    }

    private void checkData(SimpleRequest request) {
        String id = request.get("id");
        int versions = (int) request.get("version");
        InsuranceRule insuranceRule = insuranceRuleRepository.findOne(id);
        if (insuranceRule == null) throw new RuntimeException("规则【" + id + "】在系统中不存在。");
        if (insuranceRule.getVersion() != versions) throw new RuntimeException("记录已更新或已删除，请重新提交！");
    }

    public InsuranceRule testDeptAndInsurance(SimpleRequest request){
        String deptId = request.get("deptId");
        Dept dept = SpringManager.getBean(DeptRepository.class).findOne(deptId);

        String insuranceCompanyId = request.get("insuranceCompanyId");
        InsuranceCompany insuranceCompany = SpringManager.getBean(InsuranceCompanyRepository.class).findOne(insuranceCompanyId);
        return findByDeptAndInsuranceCompany(dept, insuranceCompany);
    }

    /**
     * 根据门店判断
     * @param request
     */
    private void checkOrCreateInsuranceRule(SimpleRequest request) {
        JSONObject jo = request.getJO();
        Dept dept = SpringManager.getBean(DeptRepository.class).findOne(jo.getString("deptId"));
        InsuranceCompany insuranceCompany = SpringManager.getBean(InsuranceCompanyRepository.class).findOne(jo.getString("insuranceCompanyId"));
        InsuranceRule insuranceRule = findByDeptAndInsuranceCompany(dept, insuranceCompany);

        if (Objects.isNull(insuranceRule)){
            //如果是不合作的保险公司则创建一个车险规则
            if (!insuranceCompany.isCooperation()){
                insuranceRule = new InsuranceRule();
                insuranceRule.setInsuranceCompany(insuranceCompany);
                insuranceRule.setCompany(dept.getCompany());
                insuranceRule.setDept(dept);
                insuranceRuleRepository.saveAndFlush(insuranceRule);
                //记录日志
                SpringManager.getBean(ApesLoggerService.class).sendSynEvent("event:ir.logger.create", MapUtil.mapper("businessType", insuranceRule.getInnerBusinessType(),
                        "businessKey", insuranceRule.getId(), "operate", "自动创建",
                        "workPostName",request.getSession() != null ? request.getSession().getAttribute("workPostName", String.class) : null,
                        "operator_id", ((User)request.getCurrentUser()).getId()));
                return;
            }
            throw new RuntimeException("没有找到车险规则，公司编码："+ dept.getCompany().getId() + "，保险公司编码："+ insuranceCompany.getId());
        }
    }

    /**
     * 根据部门、保险公司查询规则
     * 用于查询对应的车宝公司
     * @param dept Dept
     * @param insuranceCompany InsuranceCompany
     * @return InsuranceRule
     */
    public InsuranceRule findByDeptAndInsuranceCompany(Dept dept, InsuranceCompany insuranceCompany){
        InsuranceRule insuranceRule = getRuleFromDept(dept, insuranceCompany);
        return insuranceRule;
    }

    /**
     * 根据部门以及保险公司获取规则
     *
     * @param dept             服务门店
     * @param insuranceCompany 保险公司
     * @return InsuranceRule
     */
    public InsuranceRule getRuleByDeptAndInsuranceCompany(Dept dept, InsuranceCompany insuranceCompany) {
        InsuranceRule insuranceRule = insuranceRuleRepository
                .findAll(JpaDsl.toCriteria(MapUtil.mapper("insuranceCompany.id", insuranceCompany.getId(), "company.id", dept.getCompany().getId(), "valid", true)))
                .stream().findFirst().orElse(null);
        return insuranceRule;
    }

    /**
     * 根据保险公司编码与对应公司编码查询
     * @param request {"insuranceCompanyId": "", "companyId": ""}
     * @return
     */
    public InsuranceRule findByInsuranceAndCompany(SimpleRequest request) {
        JSONObject json = request.getJO();
        InsuranceRule insuranceRule = insuranceRuleRepository.findAll(JpaDsl.toCriteria(
                MapUtil.mapper("insuranceCompany.id", json.getString("insuranceCompanyId"),
                        "company.id", json.getString("companyId"), "valid", true)))
                .stream().findFirst().orElse(null);
        return insuranceRule;
    }

    private void setDamagePoint(InsuranceRule rule) {
        List<JSONObject> deptList = rule.getDeptList();
        if (Objects.nonNull(deptList) && deptList.size() > 0) {
            List<Dept> damagePoint = new ArrayList<>();
            deptList.forEach(
                    item -> {
                        Dept dept = SpringManager.getBean(DeptRepository.class).findOne(item.getString("id"));
                        damagePoint.add(dept);
                    }
            );
            rule.setDamagePoint(damagePoint);
        }
    }

    /**
     *  数据格式化给前端
     *
     */
    public Page<InsuranceRule> findAllForUi(SimpleRequest request) {
        Page<InsuranceRule> rulePage = request.getO(Page.class);
        rulePage.getContent().forEach(this::dealWithDeptList);
        return rulePage;
    }

    private  void dealWithDeptList (InsuranceRule rule) {
        List<Dept> deptList = rule.getDamagePoint();
        if (Objects.nonNull(deptList) && deptList.size() > 0) {
            List<JSONObject> dept = new ArrayList<>();
            deptList.forEach(
                    item -> {
                        JSONObject postJo = new JSONObject();
                        postJo.put("id", item.getId());
                        postJo.put("name", item.getName());
                        dept.add(postJo);
                    }
            );
            rule.setDeptList(dept);
        }
    }

    /**
     * 根据门店获取定损规则
     *
     * @param dept             门店
     * @param insuranceCompany 保险公司
     */
    public InsuranceRule getRuleFromDept(Dept dept, InsuranceCompany insuranceCompany) {
        InsuranceRule rule = insuranceRuleRepository.findAll(JpaDsl.toCriteriaByEq("dept", dept, "insuranceCompany", insuranceCompany,"valid",true))
                .stream().findFirst().orElse(null);
        if (Objects.isNull(rule)) {
            rule = insuranceRuleRepository.findByLossDept(dept.getId(), insuranceCompany.getId());
        }
        return rule;
    }
}
